import * as d3 from "d3";
import { throttle } from '@/libs/utils.js'
var preData, preOptions;
var superX, superY;
function nodeColor(d) {
  if (d.isLeafNode) {
    return '#999'
  } else {
    if (d.type == 1) {//岗位为蓝色
      return 'blue'
    } else {
      return 'green'//技能为绿色
    }
  }
}
export const initTree = (datasource, options) => {
  d3.select(`#${options.id} svg`).remove();
  d3.select(`#${options.id} div`).remove();
  if (!datasource) {
    d3.select(`#${options.id}`).append('div').attr('class', 'd3tree defGraphWrap').append('div').attr('class', 'defGraph')
      .append('div').attr('class', 'graphText').text('暂无数据');
    return;
  }
  const width = options.width;// +svg.attr("width"),
  const height = options.height;//+svg.attr("height")
  var svg = d3.select(`#${options.id}`).append('svg')
    .attr('width', width)
    .attr('height', height)
    .style("position", 'relative')
    .attr('id', `svg${options.id}`)
  // .on("mouseover", function (data, source) {
  //   console.log(data)
  //   superX = data.x - data.offsetX;
  //   superY = data.y - data.offsetY;
  // })
  // const width = document.documentElement.clientWidth - 260;
  // const height = document.documentElement.clientHeight - 100;
  var tree = d3.tree()
    .size([height, width - 160]);
  var margin = ({
    top: 10,
    right: 100,
    bottom: 10,
    left: 120
  });
  //贝塞尔曲线
  var diagonal = d3.linkHorizontal().x(d => d.y).y(d => d.x);
  const root = d3.hierarchy(datasource);

  root.x0 = height / 2;
  root.y0 = 0;
  root.descendants().forEach((d, i) => {
    d.id = i;
    d._children = d.children;
    //如果要开始渲染的时候隐藏节点，在此处根据条件判断
    // if (d.depth && d.data.name.length !== 7) d.children = null;
  });

  svg
    //			.attr("viewBox", [-margin.left, -margin.top, width, 100])
    .style("font", '14px sans-serif')
    .style("user-select", "none");


  const gLink = svg.append("g")
    .attr("fill", "none")
    .attr("stroke", "#555")
    .attr("stroke-opacity", 0.4)
    .attr("stroke-width", 1.5);

  const gNode = svg.append("g")
    .attr("cursor", "pointer")
    .attr("pointer-events", "all");

  function update(source) {
    const duration = 250;

    const nodes = root.descendants().reverse();
    const links = root.links();


    tree(root);

    let left = root;
    let right = root;
    root.eachBefore(node => {

      if (node.x < left.x) left = node;
      if (node.x > right.x) right = node;
    });

    const height = right.x - left.x + margin.top + margin.bottom;

    const transition = svg.transition()
      .duration(duration)
      .attr("viewBox", [-margin.left, left.x - margin.top, width + margin.left + margin.right, height])
      .tween("resize", window.ResizeObserver ? null : () => () => svg.dispatch("toggle"));

    // Update the nodes…
    const node = gNode.selectAll("g")
      .data(nodes, d => d.id);

    // 创建的节点先奔向之前source的位置
    const nodeEnter = node.enter().append("g")
      .attr("transform", d => `translate(${source.y0},${source.x0})`)
      .attr("fill-opacity", 0)
      .attr("stroke-opacity", 0)
      .attr('id', d => `${options.id}-${d.data.id}`)
      .on("click", (e, d) => {
        d.children = d.children ? null : d._children;
        // if (options.id == 'preTree') {
        //   options.cb();
        // }
        update(d);
      })
      .on('mousedown', function (data, source) {

        if (options.id == 'preTree' && data.which == 3) {
          if (options.isRoot) {//如果是根节点，禁止选叶子节点
            if (source.data.isLeafNode) {
              options.alertMsg();
              return;
            }
          }
          options.cb(source);
          if (preData) {
            const preIds = [];
            dgFn(preData, preIds);
            setRightClickStyle(preIds, options, source, { color: null, tcolor: '#ccc', twidth: 3, lcolor: '#555' })
            if (preData.id == source.data.id) {
              preData = null;
              options.cb(null);
              return;
            }
          }
          const ids = [];
          dgFn(source.data, ids)
          preData = JSON.parse(JSON.stringify(source.data));
          console.log(preData)
          setRightClickStyle(ids, options, source, { color: 'orange', tcolor: 'orange', twidth: 1, lcolor: 'orange', circle: 'organe' })
        }
      })
      .on("mouseover", function (data, source) {
        //console.log(d3.select(this))
        console.log(data)
        mousemoves()(data, source, options);
      })
      .on("mouseout", function (d) {
        if (!options.cb) {
          return;
        }
        if (options.id != 'preTree') {
          let el = d.target;
          let box = el.getBoundingClientRect();
          if (!(d.y > box.top - 16 && d.y < box.top + 16)) {
            options.cb({ boolean: false })
          }
        }
      })

    nodeEnter.append("circle")
      .attr("r", 5)
      .attr("fill", d => nodeColor(d.data))
      .attr("stroke-width", 1);
    nodeEnter.append("title")
      .text(d => d.data.name);
    //多行文字
    nodeEnter.append("foreignObject")
      .attr('x', d => d.children ? -106 : 0)
      .attr('y', -10)
      .attr('width', 100)
      .attr('height', 40)
      .append('xhtml:div')
      .attr('class', 'warpDivClass')
      .append('p')
      .attr('class', 'pTxtClass')
      .style('text-align', d => d.children ? 'right' : 'left')
      .append('span')
      .attr('class', 'spanClass')
      .text(d => d.data.name)
    // 所有节点奔赴新的位置
    const nodeUpdate = node.merge(nodeEnter).transition(transition)
      .attr("transform", d => `translate(${d.y},${d.x})`)
      .attr("fill-opacity", 1)
      .attr("stroke-opacity", 1);

    // 消失的节点过度效果
    const nodeExit = node.exit().transition(transition).remove()
      .attr("transform", d => `translate(${source.y},${source.x})`)
      .attr("fill-opacity", 0)
      .attr("stroke-opacity", 0);

    // Update the links…
    const link = gLink.selectAll("path")
      .data(links, d => d.target.id)


    // 新加入的线条线全部归并到source之前位置
    const linkEnter = link.enter().append("path")
      .attr("d", d => {
        const o = {
          x: source.x0,
          y: source.y0
        };
        return diagonal({
          source: o,
          target: o
        });
      })
      .attr('id', d => `link-${d.target.data.id}-${d.target.data.label}`)


    // 所有的线出现在正确的位置上
    link.merge(linkEnter).transition(transition)
      .attr("d", diagonal);

    // 即将消失的线归并到source现在的位置上
    link.exit().transition(transition).remove()
      .attr("d", d => {
        const o = {
          x: source.x,
          y: source.y
        };
        return diagonal({
          source: o,
          target: o
        });
      });

    //所有的点记录之前的位置
    root.eachBefore(d => {
      d.x0 = d.x;
      d.y0 = d.y;
    });
  }
  update(root);
}
//节流函数
function mousemoves() {
  return throttle(function (data, source, options) {
    if (!options.cb) {
      return;
    }
    if (options.id != 'preTree') {
      console.log(data)
      let el;
      if (data.path) {
        el = data.path.filter(f => f.id);
        if (el[0]) {
          options.cb({ boolean: true, left: 0, top: 0, data: source, el: el[0] })
        }
      } else {
        options.cb({ boolean: true, left: 0, top: 0, data: source, el: data.target })
      }
    }
  }, 1000)
}
//递归元素
function dgFn(obj, arr) {
  arr.push({ id: obj.id, label: obj.label, isLeafNode: obj.isLeafNode, type: obj.type });
  if (obj.children && obj.children.length) {
    obj.children.forEach(item => {
      dgFn(item, arr);
    })
  }
}
//右键选中设置样式
function setRightClickStyle(arr, options, source, setOption) {
  arr.forEach(item => {
    const g = d3.select(`#${options.id}-${item.id}`).attr('fill', setOption.color)//null
    g.select('text').attr('stroke-width', setOption.twidth).attr('stroke', setOption.tcolor).attr('fill', setOption.color);
    g.select('circle').attr('fill', setOption.circle ? setOption.circle : nodeColor(item));
    if (item.id !== source.data.id) {
      d3.select(`#link-${item.id}-${item.label}`).attr('stroke', setOption.lcolor)
    }
  })
}